﻿// Decompiled with JetBrains decompiler
// Type: STT.Parser.ParserSymbol
// Assembly: SymbolTypeViewer, Version=1.0.0.6, Culture=neutral, PublicKeyToken=null
// MVID: 5FAA967F-23AD-4C8B-A7DB-67BC80ACEEA3
// Assembly location: E:\VStart\安全工具\SymbolTypeViewer_v1.0_beta\SymbolTypeViewer_1_0_0_6\SymbolTypeViewer.exe

using NativeWin32;
using STT.Debug;
using System;
using System.Collections.Generic;
using System.Text;

namespace STT.Parser
{
  public static class ParserSymbol
  {
    public static class Format_C
    {
      private static SortedList<long, string> Table_BaseType = new Create_ConstToString_Table_C().Create_BaseType_Table();
      private static SortedList<long, string> Table_CallConv = new Create_ConstToString_Table_C().Create_CallConv_Table();
      private static List<string[]> Table_TypeDef = new Create_ConstToString_Table_C().Create_TypeDef_Table();
      private static List<string[]> Table_Define = new Create_ConstToString_Table_C().Create_Define_Table();

      public static string Get_Function_All(ParserSymbol.Info info)
      {
        StringBuilder stringBuilder = new StringBuilder();
        List<uint> uintList = new List<uint>();
        foreach (SymFunctionType sym_funct1 in (IEnumerable<SymFunctionType>) info.mod.list_symbol.List_FunctionType.Values)
        {
          if (sym_funct1.ChildrenCount != uint.MaxValue)
          {
            foreach (uint TypeId in sym_funct1.ArrayChildId)
            {
              Symbol symByTypeId = info.mod.list_symbol.GetSymByTypeId(TypeId);
              SymFunctionType sym_funct2 = (SymFunctionType) null;
              while (symByTypeId.TypeId_next != uint.MaxValue)
              {
                symByTypeId = info.mod.list_symbol.GetSymByTypeId(symByTypeId.TypeId_next);
                if (symByTypeId is SymFunctionType)
                {
                  sym_funct2 = (SymFunctionType) symByTypeId;
                  break;
                }
              }
              if (sym_funct2 != null && !uintList.Contains(sym_funct2.TypeId))
              {
                stringBuilder.Append(ParserSymbol.Format_C.FunctionFormat.GetFunctionFormat(info, sym_funct2));
                uintList.Add(sym_funct2.TypeId);
              }
            }
          }
          stringBuilder.Append(ParserSymbol.Format_C.FunctionFormat.GetFunctionFormat(info, sym_funct1));
          uintList.Add(sym_funct1.TypeId);
        }
        stringBuilder.AppendLine("");
        return stringBuilder.ToString();
      }

      private static string Get_Child_Struct_And_Struct_Base(
        ParserSymbol.Info info,
        SymUdt sym_udt,
        List<string> List_UnifiedName)
      {
        StringBuilder stringBuilder = new StringBuilder();
        if (sym_udt.ChildrenCount != uint.MaxValue)
        {
          foreach (uint TypeId in sym_udt.ArrayChildId)
          {
            Symbol symByTypeId = info.mod.list_symbol.GetSymByTypeId(TypeId);
            SymUdt sym_udt1 = (SymUdt) null;
            bool flag = false;
            while (!(symByTypeId is SymPointerType) && symByTypeId.TypeId_next != uint.MaxValue)
            {
              symByTypeId = info.mod.list_symbol.GetSymByTypeId(symByTypeId.TypeId_next);
              switch (symByTypeId)
              {
                case SymArrayType _:
                  flag = true;
                  continue;
                case SymUdt _:
                  if (symByTypeId.UdtKind == 0U || symByTypeId.UdtKind == 2U)
                  {
                    sym_udt1 = (SymUdt) symByTypeId;
                    if (flag && sym_udt1.UniqueName != null)
                    {
                      sym_udt1.UnnamedToNamed();
                      goto label_10;
                    }
                    else
                      goto label_10;
                  }
                  else
                    break;
              }
              flag = false;
            }
label_10:
            if (sym_udt1 != null && (sym_udt1.UniqueName != null || !List_UnifiedName.Contains(sym_udt1.SymUnifiedName)))
              stringBuilder.Append(ParserSymbol.Format_C.Get_Child_Struct_And_Struct_Base(info, sym_udt1, List_UnifiedName));
          }
        }
        if (sym_udt.UniqueName == null && !List_UnifiedName.Contains(sym_udt.SymUnifiedName))
        {
          stringBuilder.Append(ParserSymbol.Format_C.UdtFormat.GetUdtFormat(info, sym_udt));
          List_UnifiedName.Add(sym_udt.SymUnifiedName);
        }
        return stringBuilder.ToString();
      }

      public static string Get_Structure_All(ParserSymbol.Info info)
      {
        StringBuilder stringBuilder = new StringBuilder();
        List<string> List_UnifiedName = new List<string>();
        foreach (SymUdt sym_udt in info.mod.list_symbol.GetSortedArrayOfSymUdtByUnifiedName())
        {
          if (sym_udt.UniqueName == null && !List_UnifiedName.Contains(sym_udt.SymUnifiedName))
            stringBuilder.Append(ParserSymbol.Format_C.Get_Child_Struct_And_Struct_Base(info, sym_udt, List_UnifiedName));
        }
        stringBuilder.AppendLine("");
        return stringBuilder.ToString();
      }

      public static string Get_Define_All()
      {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.AppendLine("//////////////////");
        stringBuilder.AppendLine("//   C Define   //");
        stringBuilder.AppendLine("//////////////////");
        stringBuilder.AppendLine("");
        foreach (string[] strArray in ParserSymbol.Format_C.Table_Define)
        {
          stringBuilder.Append("#define ");
          stringBuilder.Append(strArray[0] + " ");
          stringBuilder.AppendLine(strArray[1]);
        }
        stringBuilder.AppendLine("//---------------------------------------------------------------------");
        stringBuilder.AppendLine("");
        return stringBuilder.ToString();
      }

      public static string Get_TypeDef_All()
      {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.AppendLine("//////////////////");
        stringBuilder.AppendLine("// C Basic Type //");
        stringBuilder.AppendLine("//////////////////");
        stringBuilder.AppendLine("");
        foreach (string[] strArray in ParserSymbol.Format_C.Table_TypeDef)
        {
          stringBuilder.Append("typedef ");
          stringBuilder.Append(strArray[0] + " ");
          stringBuilder.AppendLine(strArray[1] + ";");
        }
        stringBuilder.AppendLine("//---------------------------------------------------------------------");
        stringBuilder.AppendLine("");
        return stringBuilder.ToString();
      }

      private static string GetNameFromValue(SortedList<long, string> dico, long key)
      {
        return dico.Values[dico.IndexOfKey(key)];
      }

      private static string GetNameOfBaseType(HeaderDbghelp.BASIC_TYPE key)
      {
        return ParserSymbol.Format_C.GetNameFromValue(ParserSymbol.Format_C.Table_BaseType, (long) key);
      }

      private static string GetNameOfCallConv(HeaderDbghelp.CV_call_e key)
      {
        return ParserSymbol.Format_C.GetNameFromValue(ParserSymbol.Format_C.Table_CallConv, (long) key);
      }

      private static string Get_BaseType_Complet_Name(
        HeaderDbghelp.BASIC_TYPE BaseType,
        ulong LengthOfType)
      {
        StringBuilder stringBuilder = new StringBuilder(ParserSymbol.Format_C.GetNameOfBaseType(BaseType));
        switch (BaseType)
        {
          case HeaderDbghelp.BASIC_TYPE.btInt:
          case HeaderDbghelp.BASIC_TYPE.btUInt:
          case HeaderDbghelp.BASIC_TYPE.btFloat:
          case HeaderDbghelp.BASIC_TYPE.btLong:
          case HeaderDbghelp.BASIC_TYPE.btULong:
            stringBuilder.Append((LengthOfType * 8UL).ToString("D"));
            break;
        }
        return stringBuilder.ToString();
      }

      private static bool FormatType(
        ParserSymbol.Info info,
        Symbol sym_original,
        Stack<string> stack)
      {
        bool flag1 = false;
        bool flag2 = false;
        StringBuilder stringBuilder = new StringBuilder();
        for (Symbol symByTypeId = info.mod.list_symbol.GetSymByTypeId(sym_original.TypeId_next); symByTypeId != null; symByTypeId = info.mod.list_symbol.GetSymByTypeId(symByTypeId.TypeId_next))
        {
          switch ((HeaderDbghelp.SymTagEnum)symByTypeId.SymTag)
          {
            case HeaderDbghelp.SymTagEnum.SymTagData:
              stack.Push("/*SymTagData*/");
              break;
            case HeaderDbghelp.SymTagEnum.SymTagUDT:
              if ((flag1 || flag2) && symByTypeId.UniqueName != null)
                stack.Push(symByTypeId.UniqueName + info.suffix_for_struc_name);
              else
                stack.Push(symByTypeId.SymUnifiedName + info.suffix_for_struc_name);
              switch ((HeaderDbghelp.UdtKind)symByTypeId.UdtKind) {
                case HeaderDbghelp.UdtKind.UdtStruct:
                  stack.Push("struct ");
                  break;
                case HeaderDbghelp.UdtKind.UdtClass:
                  stack.Push("class ");
                  break;
                case HeaderDbghelp.UdtKind.UdtUnion:
                  stack.Push("union ");
                  break;
              }
              break;
            case HeaderDbghelp.SymTagEnum.SymTagEnum:
              if (symByTypeId.UniqueName != null)
                stack.Push(symByTypeId.UniqueName + info.suffix_for_struc_name);
              else
                stack.Push(symByTypeId.SymUnifiedName + info.suffix_for_struc_name);
              stack.Push("enum ");
              return true;
            case HeaderDbghelp.SymTagEnum.SymTagFunctionType:
              stack.Push(symByTypeId.SymName + info.suffix_for_struc_name);
              return true;
            case HeaderDbghelp.SymTagEnum.SymTagPointerType:
              stack.Push("*");
              flag2 = true;
              break;
            case HeaderDbghelp.SymTagEnum.SymTagArrayType:
              stack.Push(string.Format("[{0:D}]", (object) symByTypeId.ArrayElementCount));
              flag1 = true;
              break;
            case HeaderDbghelp.SymTagEnum.SymTagBaseType:
              stack.Push(ParserSymbol.Format_C.Get_BaseType_Complet_Name((HeaderDbghelp.BASIC_TYPE) symByTypeId.BaseType, symByTypeId.LengthOfType));
              break;
            case HeaderDbghelp.SymTagEnum.SymTagFunctionArgType:
              stack.Push("/*SymTagFunctionArgType*/");
              break;
            default:
              stack.Push("/*Unknown symbol. Tag : " + Program.dbg_service.GetNameOfSymTag((long) symByTypeId.SymTag) + "*/");
              return false;
          }
        }
        return true;
      }

      public static class UdtFormat
      {
        private static void GetUdtFormat(
          ParserSymbol.Info info,
          SymUdt udt_sym,
          Array_Format array_format,
          Data_Member origine_data_member,
          uint local_level,
          ulong local_offset,
          uint index_padding_name)
        {
          UdtFormatGeneric udtFormatGeneric = new UdtFormatGeneric(info.mod, udt_sym);
          for (int index = 0; index < udtFormatGeneric.list_member.Count; ++index)
          {
            SymbolGenericFormat symbolGenericFormat1 = udtFormatGeneric.list_member[index];
            switch (symbolGenericFormat1)
            {
              case StartBlock _:
                StartBlock startBlock = (StartBlock) symbolGenericFormat1;
                array_format.Indent((uint) ((int) local_level + (int) startBlock.level - 1));
                if (startBlock.IsGlobal() && origine_data_member == null)
                  array_format.Add("typedef ");
                if (startBlock.IsGeneralStruct())
                  array_format.Add("struct ");
                else if (startBlock.IsUnion())
                  array_format.Add("union ");
                if (startBlock.IsGlobal() && origine_data_member == null)
                  array_format.Add(udt_sym.SymUnifiedName + info.suffix_for_struc_name);
                array_format.AddEndAndNewLine(string.Format("// {0:D} elements, 0x{1:X} bytes (sizeof)", (object) startBlock.number_of_member, (object) startBlock.size_max));
                array_format.Indent((uint) ((int) local_level + (int) startBlock.level - 1));
                array_format.AddLine("{");
                break;
              case EndBlock _:
                EndBlock endBlock = (EndBlock) symbolGenericFormat1;
                array_format.Indent(local_level + endBlock.level);
                array_format.Add("}");
                if (endBlock.level == 0U)
                {
                  if (origine_data_member != null)
                  {
                    array_format.Add(origine_data_member.sym_data_member.SymName);
                    array_format.AddLine(";");
                    if (endBlock.start_block.padding > 0UL)
                    {
                      array_format.AddStart(string.Format("/*0x{0:X3}*/", (object) (ulong) ((long) endBlock.start_block.size_max - (long) endBlock.start_block.padding)));
                      array_format.Indent((uint) ((int) local_level + (int) endBlock.level + 1));
                      array_format.AddLine(string.Format("UINT8        _PADDING{0}_[0x{1:X}];", (object) index_padding_name, (object) endBlock.start_block.padding));
                      ++index_padding_name;
                      break;
                    }
                    break;
                  }
                  string s = udt_sym.SymUnifiedName.Substring(1) + info.suffix_for_struc_name;
                  array_format.Add(s);
                  array_format.Add(", *P");
                  array_format.Add(s);
                  array_format.AddLine(";");
                  break;
                }
                array_format.AddLine(";");
                break;
              case Data_Member _:
                Data_Member origine_data_member1 = (Data_Member) symbolGenericFormat1;
                ulong local_offset1 = origine_data_member1.GetOffset() + local_offset;
                Symbol firstSymType1 = origine_data_member1.GetFirstSymType();
                if (firstSymType1 is SymUdt && firstSymType1.UniqueName != null)
                {
                  uint num = 0;
                  if (index > 0)
                  {
                    SymbolGenericFormat symbolGenericFormat2 = udtFormatGeneric.list_member[index - 1];
                    if (symbolGenericFormat2 is Data_Member)
                    {
                      Symbol firstSymType2 = ((Data_Member) symbolGenericFormat2).GetFirstSymType();
                      if (firstSymType2 is SymUdt && (int) firstSymType2.UdtKind != (int) firstSymType1.UdtKind && firstSymType2.UniqueName != null)
                        ++num;
                    }
                  }
                  ParserSymbol.Format_C.UdtFormat.GetUdtFormat(info, (SymUdt) firstSymType1, array_format, origine_data_member1, local_level + num + origine_data_member1.level, local_offset1, index_padding_name);
                  break;
                }
                array_format.AddStart(string.Format("/*0x{0:X3}*/", (object) local_offset1));
                array_format.Indent(local_level + origine_data_member1.level);
                string s1 = ParserSymbol.Format_C.UdtFormat.FormatMemberToString(info, origine_data_member1.sym_data_member);
                int num1 = s1.LastIndexOf("//");
                if (num1 != -1)
                {
                  array_format.Add(s1.Substring(0, num1));
                  array_format.AddEndAndNewLine(s1.Substring(num1));
                }
                else
                {
                  array_format.Add(s1);
                  if (origine_data_member1.sym_data_member.BitField)
                    array_format.AddEndAndNewLine(string.Format("// {0:D} BitPosition", (object) origine_data_member1.sym_data_member.BitPosition));
                  else if (firstSymType1 is SymUdt)
                    array_format.AddEndAndNewLine(string.Format("// {0:D} elements, 0x{1:X} bytes (sizeof)", (object) firstSymType1.ChildrenCount, (object) firstSymType1.LengthOfType));
                  else
                    array_format.AddLine("");
                }
                if (origine_data_member1.padding > 0UL)
                {
                  array_format.AddStart(string.Format("/*0x{0:X3}*/", (object) (ulong) ((long) local_offset1 + (long) origine_data_member1.GetLength())));
                  array_format.Indent(local_level + origine_data_member1.level);
                  array_format.AddLine(string.Format("UINT8        _PADDING{0}_[0x{1:X}];", (object) index_padding_name, (object) origine_data_member1.padding));
                  ++index_padding_name;
                  break;
                }
                break;
            }
          }
        }

        public static string GetUdtFormat(ParserSymbol.Info info, SymUdt udt_sym)
        {
          if (udt_sym.UdtKind == 1U)
            return "";
          Array_Format array_format = new Array_Format();
          ParserSymbol.Format_C.UdtFormat.GetUdtFormat(info, udt_sym, array_format, (Data_Member) null, 0U, 0UL, 0U);
          return array_format.ToString();
        }

        public static string FormatMemberToString(ParserSymbol.Info info, SymData sym_data)
        {
          Stack<string> stack = new Stack<string>();
          StringBuilder stringBuilder1 = new StringBuilder();
          ParserSymbol.Format_C.FormatType(info, (Symbol) sym_data, stack);
          ulong LengthOfType = 0;
          for (Symbol symByTypeId = info.mod.list_symbol.GetSymByTypeId(sym_data.TypeId_next); symByTypeId != null; symByTypeId = info.mod.list_symbol.GetSymByTypeId(symByTypeId.TypeId_next))
          {
            if (symByTypeId is SymPointerType)
            {
              LengthOfType = symByTypeId.LengthOfType;
              break;
            }
          }
          if (info.fixed_pointer_size)
          {
            if (LengthOfType > 0UL)
            {
              StringBuilder stringBuilder2 = new StringBuilder("// ");
              string str;
              try
              {
                while (true)
                {
                  str = stack.Pop();
                  if (!str.StartsWith("["))
                    stringBuilder2.Append(str);
                  else
                    break;
                }
              }
              catch (Exception ex)
              {
                str = (string) null;
              }
              switch (LengthOfType)
              {
                case 4:
                  stringBuilder1.Append("ULONG32");
                  break;
                case 8:
                  stringBuilder1.Append("UINT64");
                  break;
                default:
                  stringBuilder1.Append(ParserSymbol.Format_C.Get_BaseType_Complet_Name(HeaderDbghelp.BASIC_TYPE.btUInt, LengthOfType));
                  break;
              }
              if (stringBuilder1.Length < 12)
              {
                int num = 0;
                while (num < 12 - stringBuilder1.Length)
                  stringBuilder1.Append(" ");
              }
              stringBuilder1.Append(" " + sym_data.SymName);
              if (str != null)
              {
                stringBuilder1.Append(str);
                try
                {
                  while (true)
                    stringBuilder1.Append(stack.Pop());
                }
                catch (InvalidOperationException ex)
                {
                }
              }
              stringBuilder1.Append(";");
              stringBuilder1.Append((object) stringBuilder2);
              goto label_39;
            }
          }
          string str1;
          try
          {
            while (true)
            {
              str1 = stack.Pop();
              if (!str1.StartsWith("["))
              {
                if (str1.IndexOf(":") != 1)
                  stringBuilder1.Append(str1);
                else
                  break;
              }
              else
                break;
            }
          }
          catch (InvalidOperationException ex)
          {
            str1 = (string) null;
          }
          if (stringBuilder1.Length < 12)
          {
            int num = 0;
            while (num < 12 - stringBuilder1.Length)
              stringBuilder1.Append(" ");
          }
          stringBuilder1.Append(" " + sym_data.SymName);
          if (str1 != null)
          {
            stringBuilder1.Append(str1);
            try
            {
              while (true)
                stringBuilder1.Append(stack.Pop());
            }
            catch (InvalidOperationException ex)
            {
            }
          }
          if (sym_data.BitField)
            stringBuilder1.Append(string.Format(" : {0:D}", (object) sym_data.LengthOfType));
          stringBuilder1.Append(";");
label_39:
          return stringBuilder1.ToString();
        }
      }

      public static class FunctionFormat
      {
        public static string GetFunctionFormat(ParserSymbol.Info info, SymFunctionType sym_funct)
        {
          Stack<string> stack = new Stack<string>();
          StringBuilder stringBuilder = new StringBuilder("typedef ");
          ParserSymbol.Format_C.FormatType(info, (Symbol) sym_funct, stack);
          ulong LengthOfType1 = 0;
          for (Symbol symByTypeId = info.mod.list_symbol.GetSymByTypeId(sym_funct.TypeId_next); symByTypeId != null; symByTypeId = info.mod.list_symbol.GetSymByTypeId(symByTypeId.TypeId_next))
          {
            if (symByTypeId is SymPointerType)
            {
              LengthOfType1 = symByTypeId.LengthOfType;
              break;
            }
          }
          if (info.fixed_pointer_size)
          {
            if (LengthOfType1 > 0UL)
            {
              switch (LengthOfType1)
              {
                case 4:
                  stringBuilder.Append("ULONG32");
                  break;
                case 8:
                  stringBuilder.Append("UINT64");
                  break;
                default:
                  stringBuilder.Append(ParserSymbol.Format_C.Get_BaseType_Complet_Name(HeaderDbghelp.BASIC_TYPE.btUInt, LengthOfType1));
                  break;
              }
              stringBuilder.Append(" /*");
            }
          }
          try
          {
            while (true)
              stringBuilder.Append(stack.Pop());
          }
          catch (InvalidOperationException ex)
          {
          }
          if (info.fixed_pointer_size && LengthOfType1 > 0UL)
            stringBuilder.Append("*/");
          stringBuilder.Append(" (");
          stringBuilder.Append(ParserSymbol.Format_C.GetNameOfCallConv((HeaderDbghelp.CV_call_e) sym_funct.CallConv));
          stringBuilder.Append(" ");
          stringBuilder.Append(sym_funct.SymName + info.suffix_for_struc_name);
          stringBuilder.Append(") (");
          uint num = 0;
          while (num < sym_funct.ChildrenCount)
          {
            SymFunctionArgType symByTypeId1 = (SymFunctionArgType) info.mod.list_symbol.GetSymByTypeId(sym_funct.ArrayChildId[(int)(IntPtr) num++]);
            if (num > 1U)
              stringBuilder.Append(", ");
            stack.Clear();
            ParserSymbol.Format_C.FormatType(info, (Symbol) symByTypeId1, stack);
            ulong LengthOfType2 = 0;
            for (Symbol symByTypeId2 = info.mod.list_symbol.GetSymByTypeId(symByTypeId1.TypeId_next); symByTypeId2 != null; symByTypeId2 = info.mod.list_symbol.GetSymByTypeId(symByTypeId2.TypeId_next))
            {
              if (symByTypeId2 is SymPointerType)
              {
                LengthOfType2 = symByTypeId2.LengthOfType;
                break;
              }
            }
            if (info.fixed_pointer_size)
            {
              if (LengthOfType2 > 0UL)
              {
                switch (LengthOfType2)
                {
                  case 4:
                    stringBuilder.Append("ULONG32");
                    break;
                  case 8:
                    stringBuilder.Append("UINT64");
                    break;
                  default:
                    stringBuilder.Append(ParserSymbol.Format_C.Get_BaseType_Complet_Name(HeaderDbghelp.BASIC_TYPE.btUInt, LengthOfType2));
                    break;
                }
                stringBuilder.Append(" /*");
              }
            }
            try
            {
              while (true)
                stringBuilder.Append(stack.Pop());
            }
            catch (InvalidOperationException ex)
            {
            }
            if (info.fixed_pointer_size && LengthOfType2 > 0UL)
              stringBuilder.Append("*/");
          }
          stringBuilder.AppendLine(");");
          return stringBuilder.ToString();
        }
      }

      public static class EnumFormat
      {
        public static string FormatMemberToString(
          ParserSymbol.Info info,
          SymData sym_data,
          uint padding)
        {
          StringBuilder stringBuilder1 = new StringBuilder();
          if (info.mod != null && sym_data != null && sym_data.DataKind == 9U)
          {
            uint num1 = 0;
            stringBuilder1.Append(sym_data.SymName);
            while (num1++ < padding)
              stringBuilder1.Append(" ");
            stringBuilder1.Append(" = ");
            try
            {
              stringBuilder1.Append(string.Format("{0:D} /*0x{1:X}*/", sym_data.Value, sym_data.Value));
              if (sym_data.Value is uint)
              {
                uint num2 = (uint) sym_data.Value;
                char[] chArray = new char[4];
                bool flag = true;
                StringBuilder stringBuilder2 = new StringBuilder("  /*");
                for (int index = 0; index < chArray.Length; ++index)
                {
                  chArray[index] = (char) (byte) (num2 & (uint) byte.MaxValue);
                  if (char.IsLetterOrDigit(chArray[index]))
                  {
                    stringBuilder2.Append(chArray[index]);
                    num2 >>= 8;
                  }
                  else
                  {
                    flag = false;
                    break;
                  }
                }
                if (flag)
                {
                  stringBuilder2.Append("*/");
                  stringBuilder1.Append(stringBuilder2.ToString());
                }
              }
            }
            catch
            {
              stringBuilder1.Append("?");
            }
          }
          return stringBuilder1.ToString();
        }

        public static string GetEnumFormat(ParserSymbol.Info info, SymEnum sym_enum)
        {
          StringBuilder stringBuilder = new StringBuilder();
          stringBuilder.Append("typedef enum ");
          string str1 = sym_enum.UniqueName == null ? sym_enum.SymUnifiedName + info.suffix_for_struc_name : sym_enum.UniqueName + info.suffix_for_struc_name;
          stringBuilder.Append(str1);
          stringBuilder.AppendFormat("  // {0} elements, 0x{1:X} bytes\n", (object) sym_enum.ChildrenCount, (object) sym_enum.LengthOfType);
          stringBuilder.AppendLine("{");
          if (sym_enum.ChildrenCount > 0U)
          {
            int num1 = 0;
            int num2 = 0;
            while ((long) num2 < (long) sym_enum.ChildrenCount)
            {
              int length = info.mod.list_symbol.GetSymByTypeId(sym_enum.ArrayChildId[num2++]).SymName.Length;
              if (length > num1)
                num1 = length;
            }
            for (int index = 0; (long) index < (long) sym_enum.ChildrenCount; ++index)
            {
              SymData symByTypeId = (SymData) info.mod.list_symbol.GetSymByTypeId(sym_enum.ArrayChildId[index]);
              if (index != 0)
                stringBuilder.AppendLine(",");
              stringBuilder.Append("    ");
              int num3 = num1 - symByTypeId.SymName.Length;
              stringBuilder.Append(ParserSymbol.Format_C.EnumFormat.FormatMemberToString(info, symByTypeId, (uint) num3));
            }
            stringBuilder.AppendLine("");
          }
          stringBuilder.Append("}");
          string str2 = str1.Substring(1);
          stringBuilder.Append(str2);
          stringBuilder.Append(", *P");
          stringBuilder.Append(str2);
          stringBuilder.AppendLine(";");
          stringBuilder.AppendLine("");
          return stringBuilder.ToString();
        }
      }
    }

    public class Info
    {
      public ModuleSymbols mod;
      public bool fixed_pointer_size;
      public string suffix_for_struc_name;

      public Info(ModuleSymbols _mod, bool _fixed_pointer_size, string _suffix_for_struc_name)
      {
        this.mod = _mod;
        this.fixed_pointer_size = _fixed_pointer_size;
        this.suffix_for_struc_name = _suffix_for_struc_name;
      }
    }

    public static class Format_IDA
    {
      public static string GetBaseTypeByLength(ulong LengthOfType)
      {
        switch (LengthOfType)
        {
          case 1:
            return "FF_BYTE";
          case 2:
            return "FF_WORD";
          case 4:
            return "FF_DWRD";
          case 8:
            return "FF_QWRD";
          case 16:
            return "FF_OWRD";
          default:
            return "FF_???_size_" + (object) LengthOfType;
        }
      }

      private static string Get_Child_Struct_And_Struct_Base(
        ParserSymbol.Info info,
        UdtFormatGeneric udt_format_generic,
        int index_start_block,
        List<string> List_UnifiedName)
      {
        StringBuilder stringBuilder = new StringBuilder();
        int num = index_start_block;
        StartBlock startBlock = (StartBlock) udt_format_generic.list_member[index_start_block];
        for (int index_start_block1 = num + 1; index_start_block1 < udt_format_generic.list_member.Count; ++index_start_block1)
        {
          SymbolGenericFormat symbolGenericFormat = udt_format_generic.list_member[index_start_block1];
          switch (symbolGenericFormat)
          {
            case EndBlock _:
              if (startBlock.end_block != (EndBlock) symbolGenericFormat)
                break;
              goto label_15;
            case StartBlock _:
              stringBuilder.Append(ParserSymbol.Format_IDA.Get_Child_Struct_And_Struct_Base(info, udt_format_generic, index_start_block1, List_UnifiedName));
              break;
            case Data_Member _:
              Data_Member dataMember = (Data_Member) symbolGenericFormat;
              Symbol symDataMember = (Symbol) dataMember.sym_data_member;
              SymUdt _sym_udt = (SymUdt) null;
              foreach (uint TypeId in dataMember.list_typeid)
              {
                Symbol symByTypeId = udt_format_generic.mod.list_symbol.GetSymByTypeId(TypeId);
                if (!(symByTypeId is SymPointerType))
                {
                  if (symByTypeId is SymUdt && (symByTypeId.UdtKind == 0U || symByTypeId.UdtKind == 2U))
                  {
                    _sym_udt = (SymUdt) symByTypeId;
                    break;
                  }
                }
                else
                  break;
              }
              if (_sym_udt != null && (_sym_udt.UniqueName != null || !List_UnifiedName.Contains(_sym_udt.SymUnifiedName)))
              {
                stringBuilder.Append(ParserSymbol.Format_IDA.Get_Child_Struct_And_Struct_Base(info, new UdtFormatGeneric(info.mod, _sym_udt), 0, List_UnifiedName));
                break;
              }
              break;
          }
        }
label_15:
        string str = startBlock.UniqueName == null ? (udt_format_generic.sym_udt.UniqueName == null ? udt_format_generic.sym_udt.SymUnifiedName : udt_format_generic.sym_udt.UniqueName) : startBlock.UniqueName;
        if (!List_UnifiedName.Contains(str))
        {
          stringBuilder.AppendLine("//------------------------------------------------------------------------");
          stringBuilder.Append(ParserSymbol.Format_IDA.UdtFormat.GetUdtFormat(info, udt_format_generic, index_start_block));
          List_UnifiedName.Add(str);
        }
        return stringBuilder.ToString();
      }

      public static string Get_Structure_All(ParserSymbol.Info info)
      {
        StringBuilder stringBuilder = new StringBuilder();
        List<string> List_UnifiedName = new List<string>();
        foreach (SymUdt _sym_udt in info.mod.list_symbol.GetSortedArrayOfSymUdtByUnifiedName())
        {
          string str = _sym_udt.UniqueName != null ? _sym_udt.UniqueName : _sym_udt.SymUnifiedName;
          if (!List_UnifiedName.Contains(str))
            stringBuilder.Append(ParserSymbol.Format_IDA.Get_Child_Struct_And_Struct_Base(info, new UdtFormatGeneric(info.mod, _sym_udt), 0, List_UnifiedName));
        }
        stringBuilder.AppendLine("");
        return stringBuilder.ToString();
      }

      public static class UdtFormat
      {
        public static string GetUdtFormat(ParserSymbol.Info info, SymUdt udt_sym)
        {
          return ParserSymbol.Format_IDA.UdtFormat.GetUdtFormat(info, new UdtFormatGeneric(info.mod, udt_sym), 0);
        }

        public static string GetUdtFormat(
          ParserSymbol.Info info,
          UdtFormatGeneric udt_format_generic,
          int index_start_block)
        {
          Array_Format array_format = new Array_Format();
          StartBlock startBlock1 = (StartBlock) udt_format_generic.list_member[index_start_block];
          array_format.Indent(1U);
          array_format.Add("id = ");
          array_format.Add("AddStrucEx(-1,\"");
          if (startBlock1.UniqueName != null)
            array_format.Add(startBlock1.UniqueName + info.suffix_for_struc_name);
          else if (udt_format_generic.sym_udt.UniqueName != null)
            array_format.Add(udt_format_generic.sym_udt.UniqueName + info.suffix_for_struc_name);
          else
            array_format.Add(udt_format_generic.sym_udt.SymUnifiedName + info.suffix_for_struc_name);
          array_format.Add("\", ");
          if (startBlock1.IsStruct())
            array_format.AddLine("0);");
          else if (startBlock1.IsUnion() || startBlock1.IsBitsStruct())
            array_format.AddLine("1);");
          else
            array_format.AddLine("0xFFFFFFFF);");
          string format1 = "SetStrucComment (id,\"{0:D} elements, sizeof = 0x{1:X} bytes\", 0);";
          array_format.Indent(1U);
          array_format.AddLine(string.Format(format1, (object) startBlock1.number_of_member, (object) startBlock1.size_max));
          array_format.AddLine("");
          ++index_start_block;
          while (index_start_block < udt_format_generic.list_member.Count)
          {
            SymbolGenericFormat symbolGenericFormat = udt_format_generic.list_member[index_start_block];
            if (symbolGenericFormat is EndBlock)
            {
              if (startBlock1.end_block == (EndBlock) symbolGenericFormat)
                break;
            }
            else
            {
              if ((object) (symbolGenericFormat as StartBlock) != null)
              {
                StartBlock startBlock2 = (StartBlock) symbolGenericFormat;
                array_format.Indent(1U);
                array_format.Add("id_temp = ");
                array_format.Add("GetStrucIdByName(\"");
                array_format.Add(startBlock2.UniqueName + info.suffix_for_struc_name);
                array_format.AddLine("\");");
                array_format.Indent(1U);
                array_format.Add("AddStrucMember(id, \"_");
                if (startBlock2.IsStruct())
                  array_format.Add("struc");
                else
                  array_format.Add("union");
                string format2 = "_{0:D}\", {1:D}";
                array_format.Add(string.Format(format2, (object) index_start_block, (object) startBlock2.offset_base));
                array_format.AddLine(", FF_STRU, id_temp, GetStrucSize(id_temp));");
                index_start_block = udt_format_generic.list_member.IndexOf((SymbolGenericFormat) startBlock2.end_block);
                continue;
              }
              if (symbolGenericFormat is Data_Member)
              {
                Data_Member dataMember = (Data_Member) symbolGenericFormat;
                ParserSymbol.Format_IDA.UdtFormat.FormatMemberToString(info, dataMember.sym_data_member, (long) dataMember.GetOffset() - (long) startBlock1.GetOffset(), array_format);
              }
            }
            ++index_start_block;
          }
          array_format.AddLine("");
          string format3 = "if (GetStrucSize(id)<{0:D})";
          array_format.Indent(1U);
          array_format.AddLine(string.Format(format3, (object) startBlock1.size_max));
          array_format.Indent(1U);
          array_format.AddLine("{");
          string format4 = "AddStrucMember(id, \"_Padding\", -1, FF_DATA | FF_BYTE, -1, {0:D}-GetStrucSize(id));";
          array_format.Indent(2U);
          array_format.AddLine(string.Format(format4, (object) startBlock1.size_max));
          array_format.Indent(1U);
          array_format.AddLine("}");
          return array_format.ToString();
        }

        public static string FormatMemberToString(ParserSymbol.Info info, SymData sym_data)
        {
          Array_Format array_format = new Array_Format();
          ParserSymbol.Format_IDA.UdtFormat.FormatMemberToString(info, sym_data, -1L, array_format);
          return array_format.ToString();
        }

        public static void FormatMemberToString(
          ParserSymbol.Info info,
          SymData sym_data,
          long offset,
          Array_Format array_format)
        {
          StringBuilder stringBuilder = new StringBuilder();
          SymUdt symUdt = (SymUdt) null;
          uint num = 1;
          Symbol symByTypeId = info.mod.list_symbol.GetSymByTypeId(sym_data.TypeId_next);
          while (true)
          {
            switch (symByTypeId)
            {
              case SymArrayType _:
                num *= symByTypeId.ArrayElementCount;
                symByTypeId = info.mod.list_symbol.GetSymByTypeId(symByTypeId.TypeId_next);
                continue;
              case SymUdt _:
                goto label_2;
              default:
                goto label_4;
            }
          }
label_2:
          symUdt = (SymUdt) symByTypeId;
label_4:
          string symName = sym_data.SymName;
          if (symName.Length < 3)
            symName += "__";
          if (symUdt != null)
          {
            array_format.Indent(1U);
            array_format.Add("id_temp = ");
            array_format.Add("GetStrucIdByName(\"");
            if (symUdt.UniqueName != null)
              array_format.Add(symUdt.UniqueName + info.suffix_for_struc_name);
            else
              array_format.Add(symUdt.SymUnifiedName + info.suffix_for_struc_name);
            array_format.AddLine("\");");
            array_format.Indent(1U);
            array_format.Add("AddStrucMember(id, \"");
            array_format.Add(symName);
            string format = "\", {0:D}, FF_STRU, id_temp, GetStrucSize(id_temp)";
            array_format.Add(string.Format(format, (object) offset));
          }
          else
          {
            array_format.Indent(1U);
            array_format.Add("AddStrucMember(id, \"");
            array_format.Add(symName);
            string format = "\", {0:D}, FF_DATA | ";
            array_format.Add(string.Format(format, (object) offset));
            if (symByTypeId.SymTag == 14U)
            {
              array_format.Add(ParserSymbol.Format_IDA.GetBaseTypeByLength(symByTypeId.LengthOfType));
              array_format.Add(string.Format(", -1, {0:D}", (object) symByTypeId.LengthOfType));
            }
            else if (symByTypeId.SymTag == 12U)
            {
              array_format.Add(ParserSymbol.Format_IDA.GetBaseTypeByLength(symByTypeId.LengthOfType));
              array_format.Add(string.Format(", -1, {0:D}", (object) symByTypeId.LengthOfType));
            }
            else if (symByTypeId.SymTag == 16U)
            {
              array_format.Add(ParserSymbol.Format_IDA.GetBaseTypeByLength(symByTypeId.LengthOfType));
              array_format.Add(string.Format(", -1, {0:D}", (object) symByTypeId.LengthOfType));
            }
            else
              array_format.Add("FF_DWRD_???, -1, 4_???");
          }
          if (num > 1U)
            array_format.Add(string.Format("*{0:D}", (object) num));
          array_format.AddLine(");");
        }
      }

      public static class EnumFormat
      {
        public static string FormatMemberToString(ParserSymbol.Info info, SymData sym_data)
        {
          Array_Format array_format = new Array_Format();
          ParserSymbol.Format_IDA.EnumFormat.FormatMemberToString(info, sym_data, array_format);
          return array_format.ToString();
        }

        public static void FormatMemberToString(
          ParserSymbol.Info info,
          SymData sym_data,
          Array_Format array_format)
        {
          StringBuilder stringBuilder1 = new StringBuilder();
          if (info.mod == null || sym_data == null || sym_data.DataKind != 9U)
            return;
          string symName = sym_data.SymName;
          if (symName.Length < 3)
            symName += "__";
          array_format.Indent(1U);
          array_format.Add("AddConstEx(id, \"");
          array_format.Add(symName);
          array_format.Add("\", ");
          try
          {
            array_format.Add(string.Format("{0:D}", sym_data.Value));
          }
          catch
          {
            array_format.Add("?");
          }
          array_format.AddLine(", -1);");
          stringBuilder1.Append(string.Format("0x{0:X}", sym_data.Value));
          if (sym_data.Value is uint)
          {
            uint num = (uint) sym_data.Value;
            char[] chArray = new char[4];
            bool flag = true;
            StringBuilder stringBuilder2 = new StringBuilder("  ->  ");
            for (int index = 0; index < chArray.Length; ++index)
            {
              chArray[index] = (char) (byte) (num & (uint) byte.MaxValue);
              if (char.IsLetterOrDigit(chArray[index]))
              {
                stringBuilder2.Append(chArray[index]);
                num >>= 8;
              }
              else
              {
                flag = false;
                break;
              }
            }
            if (flag)
              stringBuilder1.Append(stringBuilder2.ToString());
          }
          array_format.Indent(1U);
          array_format.Add(string.Format("SetConstCmt(GetConstEx(id,{0:D},0,-1),\"", sym_data.Value));
          array_format.Add(stringBuilder1.ToString());
          array_format.AddLine("\",0);");
        }

        public static string GetEnumFormat(ParserSymbol.Info info, SymEnum sym_enum)
        {
          Array_Format array_format = new Array_Format();
          array_format.Indent(1U);
          array_format.Add("id = ");
          array_format.Add("AddEnum(-1,\"");
          if (sym_enum.UniqueName != null)
            array_format.Add(sym_enum.UniqueName + info.suffix_for_struc_name);
          else
            array_format.Add(sym_enum.SymUnifiedName + info.suffix_for_struc_name);
          array_format.AddLine("\", FF_0NUMD | FF_1NUMD );");
          array_format.AddLine("");
          if (sym_enum.ChildrenCount != uint.MaxValue)
          {
            foreach (uint TypeId in sym_enum.ArrayChildId)
            {
              Symbol symByTypeId = info.mod.list_symbol.GetSymByTypeId(TypeId);
              if (symByTypeId != null && symByTypeId is SymData)
                ParserSymbol.Format_IDA.EnumFormat.FormatMemberToString(info, (SymData) symByTypeId, array_format);
            }
          }
          return array_format.ToString();
        }
      }
    }
  }
}
